package org.yagnus.stats.samplers.discrete.withoutreplacement;

import java.util.ArrayList;
import java.util.List;

import org.yagnus.stats.samplers.discrete.ListSampler;

/**
 * @author hc.busy
 * @param <T>
 * 
 *            For all subclasses these should be possible. TODO: check a full
 *            takeAll, where check newly sampled item is unique and remaining
 *            item count is right, and new item is not in remaining sample, etc.
 * 
 *            TODO: Fairly large check for uniform: Check counts after repeated
 *            sample of a fixed fraction (take(30) of sample of space of 100,
 *            and compare the occurrence count of each of the 100 samples.
 *            chi-sq vs. multinomial with theoretical.(Theoretical available in
 *            closed form only for uniform)
 * 
 */
public abstract class WithoutReplacementSampler<T> extends ListSampler<T> {

	/**
	 * implementing class need to keep this number up to date. len is the size
	 * of the current sample space
	 */
	int numberSampled, len;

	public int getNumberSampled() {
		return numberSampled;
	}

	/**
	 * 
	 * Takes an item out of the space and returns it.
	 * 
	 * @return the item taken out of sample space
	 * 
	 */
	public abstract T take();

	/**
	 * 
	 * Derived classes should implement more efficient version if possible
	 * 
	 * @return sampling of the rest in the order in which they were sampled.
	 * 
	 */
	public List<T> takeAll() {
		ArrayList<T> ret = new ArrayList<T>();
		for (T t = take(); t != null; t = take()) {
			ret.add(t);
		}
		return ret;
	}

	public WithoutReplacementSampler(List<T> t) {
		super(t);
		numberSampled = 0;
	}

	public WithoutReplacementSampler(List<T> t, List<Double> weights) {
		super(t, weights);
		numberSampled = 0;
	}

	public abstract void reset();

	public abstract int remaining();
}
